
--[[
local root = require("Loader").load('UI.xx')
local group = TouchGroup:create()
group:addWidget(root)
your_node:addChild(group)

root.button1.image2:setScale(1.1)
root.button1:onClicked(function()
--do your stuff
end)
]]

local defines = require("Attribute")()
local has_custom, err = pcall(require , "custom_Attribute")

local constructor = {}

for type, v in pairs(defines) do
    if v._custom then
        constructor[type] = function() return v.ctor() end
    else
        local cls = _G[type]
        constructor[type] = function() return cls:create() end
    end
end

local function create(type)
    return constructor[type]()
end

local function loadWidget(load_f, t, parent)
    local widget = create(t.class)

    parent[t.Name] = widget
    parent:addChild(widget)

    local attr = defines[t.class]

    for k, v in pairs(t) do
        if type(v) ~= 'table' then
            local acc = attr[k]
            if acc and acc.set then
                acc.set(widget, v)
            else
                print('[Warning] not set', k, v)
            end
        end
    end

    for i, v in ipairs(t) do
        load_f(load_f, v, widget)
    end
end

local function loadT(load_f, t, pre_load_f)
    local root = Widget:create()

    if pre_load_f then
        pre_load_f(root)
    end

    for i, v in ipairs(t) do
        load_f(load_f, v, root)
    end

    return root
end

local function loadS(load_f, s, pre_load_f)
    return loadT(load_f, loadstring(s)(), pre_load_f)
end

local util = CCFileUtils:sharedFileUtils()
local getFileData = function(filename) return util:getFileData(filename) end

local function loadF(load_f, filename, pre_load_f)
    return loadS(load_f, getFileData(filename), pre_load_f)
end

---

local Loader = {}

function Loader.setReadFunc(f) getFileData = f end

function Loader.loadS(s) return loadS(loadWidget, s) end
function Loader.loadT(t) return loadT(loadWidget, t) end
function Loader.load(f)  return loadF(loadWidget, f) end

function Loader.loadxx(file)
    local root = loadF(loadWidget, file)

    local group = TouchGroup:create()
    group:addWidget(root)
    group.root = root

    return group
end

--

local function loadStep(file, speed)
    local counter = 0

    speed = speed or 1

    local function stepLoader(...)
        counter = counter + 1
        if counter >= speed then
            counter = 0
            coroutine.yield()
        end
        return loadWidget(...)
    end

    local root = loadF(stepLoader, file, function(root)
        coroutine.yield(root)
    end)

    coroutine.yield(root)
end

--[[
file        : filename to load
done_func   : call when done
speed       : load widgets count each frame
--]]
function Loader.stepLoad(file, touchgroup, done_func, speed)
    local thread = coroutine.create(loadStep)
    local ok, root = coroutine.resume(thread, file, speed)

    if not ok then
        return print(root)
    end

    touchgroup:addWidget(root)
    root:hide()

    root:addNodeEventListener(cc.NODE_ENTER_FRAME_EVENT, function(dt)

            local ok, ret = coroutine.resume(thread)

            if ret then
                root:unscheduleUpdate()
                if not ok then
                    print(ret)
                else
                    root:show()
                    done_func(ret)
                end
            end
    end)

    root:scheduleUpdate_()
end

function Loader.stepLoadxx(file, parent, func, speed)
    Loader.stepLoad(file, TouchGroup:create():addTo(parent), func, speed)
end

return Loader